home *** CD-ROM | disk | FTP | other *** search
/ Megahits 5 / Megahits 5 (1994)(GTI - Rhein-Main-Soft)(DE)(Disc 2 of 2)[!].iso / archive / show / jmore03.lzh / jmoresrc.LZH / jFontSys.c < prev    next >
C/C++ Source or Header  |  1992-11-04  |  7KB  |  369 lines

  1. /*
  2.  *    jFontSys.c
  3.  *    H.Ohkubo Oct. 19, 1992
  4.  */
  5. #include    <exec/types.h>
  6. #include    <exec/ports.h>
  7. #include    <graphics/text.h>
  8. #include    <functions.h>
  9. #include    <stdio.h>
  10. #include    <stdlib.h>
  11. #include    <limits.h>
  12. #include    <string.h>
  13. #include    <ctype.h>
  14. #include    "jFont.h"
  15. #include    "jFontSys.h"
  16. #include    "openlib.h"
  17.  
  18. struct    MsgPort    *jFontPort = NULL;
  19.  
  20. struct    TextAttr    textattr = {
  21.     NULL,    /* set font name, later */
  22.     FONT_SIZE,    /* font height */
  23.     FS_NORMAL,    /* style is normal. not bold, not italic, not... */ 
  24.     FPF_DISKFONT,    /* this is Disk font. */
  25.     };
  26.  
  27. struct    font_cache    cache[FONT_CACHE_MAX], cache_list;
  28.  
  29. int    cache_size = FONT_CACHE_SIZE;
  30. BOOL    denec = FALSE;
  31. char    jfontname[FNAMELEN];
  32.  
  33. #ifdef    DEBUG
  34. int    cache_hit = 0, cache_missed = 0;    /* for font cache effect check */
  35. #endif
  36.  
  37.  
  38. /* prototypes */
  39. struct    TextFont    *open_font(USHORT);
  40. struct    TextFont    *open_font_doit(char *);
  41. VOID    insert_font(struct font_cache *, struct font_cache *);
  42. struct    font_cache    *remove_font(struct font_cache *);
  43. VOID    init_font_cache(VOID);
  44. VOID    free_font_cache(VOID);
  45. struct    MsgPort    *set_jfont(VOID);
  46. VOID    remove_jfont(struct MsgPort *, BOOL);
  47. VOID    get_startup(VOID);
  48. VOID    init_default(VOID);
  49. int    set_startup_value(FILE *);
  50. char    *my_getline(FILE *);
  51. int    set_cache_size(int);
  52. VOID    clean_exit(char *, int);
  53.  
  54.  
  55. VOID    main(int argc, char *argv[])
  56. {
  57.     struct    jFontMsg    *msg;
  58.     int    done = FALSE;
  59.     BOOL    fromwb = TRUE;
  60.  
  61.     if (argc != 0) {
  62.         puts(COPYRIGHT);
  63.         fromwb = FALSE;
  64.     }
  65.  
  66.     if ((jFontPort = FindPort(JFONTPORT)) != NULL)
  67.         remove_jfont(jFontPort, fromwb);
  68.     else {
  69.         jFontPort = set_jfont();
  70.         if (!OpenLib())
  71.             clean_exit("No Library !", RETURN_FAIL);
  72.     }
  73.  
  74.     get_startup();
  75.     init_font_cache();
  76.     while (!done) {
  77.         WaitPort(jFontPort);
  78.         while (msg = (struct jFontMsg *)GetMsg(jFontPort)) {
  79.             switch (msg->kanji) {
  80.             case REMOVE_JFONT:
  81.                 while (msg = (struct jFontMsg *)GetMsg(jFontPort)) {
  82.                     msg->font = (struct TextFont *)NULL;
  83.                     ReplyMsg((struct Message *)msg);
  84.                 }
  85.                 done = TRUE;
  86.                 break;
  87.             default:
  88.                 msg->font = (struct TextFont *)open_font(msg->kanji);
  89.                 ReplyMsg((struct Message *)msg);
  90.                 break;
  91.             }
  92.         }
  93.     }
  94.     free_font_cache();
  95.  
  96.     clean_exit(END_MESSAGE, RETURN_OK);
  97. }
  98.  
  99.  
  100. /* for font cache routine */
  101. struct    TextFont    *open_font(USHORT kanji_code)
  102. {
  103.     int    fontnum;
  104.     char    fontname[FNAMELEN];
  105.  
  106.     /* kanji_code is JIS kanji-code. but this is illegal case. */
  107.     if (kanji_code == ANK_FONT_CODE)
  108.         return cache[ANK].font;
  109.  
  110.     fontnum = ((kanji_code>>CHAR_BIT)&0xff) - ' ';    /* get font file number */
  111.     if (fontnum >= SYM1 && fontnum <= KATA)
  112.         return cache[fontnum].font;
  113.  
  114.     if (denec && (fontnum > KEISEN && fontnum < JIS1))    /* NEC local? or not */
  115.         return (struct TextFont *)NULL;
  116.  
  117.     sprintf(fontname, KNJ_FONT, KANJIDIR, jfontname, fontnum);
  118.     return open_font_doit(fontname);
  119. }
  120.  
  121.  
  122. struct    TextFont    *open_font_doit(char *fontname)
  123. {
  124.     struct    font_cache    *p = &cache_list;
  125.     struct    TextFont    *font;
  126.  
  127.     for (p = p->next; p != &cache_list; p = p->next) {
  128.         if (strcmp(fontname, p->fontname) == 0) {
  129. #ifdef    DEBUG
  130.             cache_hit++;
  131. #endif
  132.             remove_font(p);
  133.             insert_font(&cache_list, p);
  134.             return p->font;
  135.         }
  136.     }
  137.  
  138.     p = remove_font(cache_list.next);
  139.     insert_font(&cache_list, p);
  140.     if (p->font) {
  141.         CloseFont(p->font);
  142.         p->font = (struct TextFont *)NULL;
  143.         p->fontname[0] = '\0';
  144.     }
  145.  
  146.     textattr.ta_Name = (STRPTR)fontname;
  147.     if ((font = OpenDiskFont(&textattr)) == NULL)
  148.         return (struct TextFont *)NULL;
  149.     p->font = font;
  150.     strcpy(p->fontname, fontname);
  151. #ifdef    DEBUG
  152.     cache_missed++;
  153. #endif
  154.     return font;
  155. }
  156.  
  157.  
  158. VOID    insert_font(struct font_cache *position, struct font_cache *x)
  159. {
  160.     position->prev->next = x;
  161.     x->prev = position->prev;
  162.     x->next = position;
  163.     position->prev = x;
  164. }
  165.  
  166.  
  167. struct    font_cache    *remove_font(struct font_cache *x)
  168. {
  169.     x->prev->next = x->next;
  170.     x->next->prev = x->prev;
  171.  
  172.     return x;
  173. }
  174.  
  175.  
  176. VOID    init_font_cache(VOID)
  177. {
  178.     int    i;
  179.  
  180.     for (i = ANK; i <= KATA; i++) {
  181.         if (i == ANK && *(cache[i].fontname) == '\0')
  182.             sprintf(cache[i].fontname, ANK_FONT);
  183.         else if (*(cache[i].fontname) == '\0')
  184.             sprintf(cache[i].fontname, KNJ_FONT, KANJIDIR, jfontname, i);
  185.         textattr.ta_Name = (STRPTR)cache[i].fontname;
  186.         if ((cache[i].font = OpenDiskFont(&textattr)) == NULL) {
  187.             free_font_cache();
  188.             clean_exit("No Font !", RETURN_FAIL);
  189.         }
  190.         cache[i].next = cache[i].prev = &cache[i];
  191.     }
  192.  
  193.     cache_list.next = cache_list.prev = &cache_list;
  194.     for (; i < cache_size; i++) {
  195.         cache[i].font = (struct TextFont *)NULL;
  196.         insert_font(&cache_list, &cache[i]);
  197.     }
  198. }
  199.  
  200.  
  201. VOID    free_font_cache(VOID)
  202. {
  203.     int    i;
  204.  
  205.     for (i = 0; i < cache_size; i++) {
  206.         if (cache[i].font)
  207.             CloseFont(cache[i].font);
  208.     }
  209.  
  210. #ifdef    DEBUG
  211.     printf("Cache Hit = %d\tCache missed = %d\n", cache_hit, cache_missed);
  212. #endif
  213. }
  214.  
  215.  
  216. /* for Message port routine */
  217. struct    MsgPort    *set_jfont(VOID)
  218. {
  219.     struct    MsgPort    *port;
  220.  
  221.     if ((port = CreatePort(JFONTPORT, NORMAL_PRI)) == NULL)
  222.         clean_exit("No Port !", RETURN_FAIL);
  223.  
  224.     return port;
  225. }
  226.  
  227.  
  228. VOID    remove_jfont(struct MsgPort *jFontPort, BOOL fromwb)
  229. {
  230.     struct    jFontMsg    sendmsg;
  231.  
  232.     sendmsg.msg.mn_Length = sizeof(struct jFontMsg);
  233.     sendmsg.kanji = REMOVE_JFONT;
  234.  
  235.     PutMsg(jFontPort, (struct Message *)&sendmsg);
  236.     if (!fromwb)
  237.         puts(REMOVE_MESSAGE);
  238.  
  239.     exit(EXIT_SUCCESS);
  240. }
  241.  
  242.  
  243. /* for startup file routine */
  244. VOID    get_startup(VOID)
  245. {
  246.     FILE    *fp;
  247.  
  248.     init_default();
  249.     if ((fp = fopen(STARTUP, READ_BINARY)) != NULL) {
  250.         while (set_startup_value(fp) != EOF)
  251.             ;
  252.         fclose(fp);
  253.     }
  254. }
  255.  
  256.  
  257. int    set_startup_value(FILE *fp)
  258. {
  259.     char    *lp, *name_end, *value_head;
  260.     int    i, c;
  261.  
  262.     lp = my_getline(fp);
  263.     if ((name_end = strchr(lp, '=')) != NULL) {
  264.         value_head = name_end + 1;
  265.         for (i = CACHE_SIZE; i < TOTAL_STARTUP; i++) {
  266.             if (strncmp(startup[i], lp, name_end - lp) == 0) {
  267.                 switch (i) {
  268.                 case CACHE_SIZE:
  269.                     cache_size = set_cache_size(atoi(value_head));
  270.                     break;
  271.                 case FONT_NAME:
  272.                     sprintf(cache[ANK].fontname,
  273.                         "%s.font", value_head);
  274.                     break;
  275.                 case JFONT_NAME:
  276.                     strcpy(jfontname, value_head);
  277.                     break;
  278.                 case SYM1_NAME:
  279.                 case SYM2_NAME:
  280.                 case JANK_NAME:
  281.                 case HIRA_NAME:
  282.                 case KATA_NAME:
  283.                     sprintf(cache[i - SYM1_NAME + 1].fontname,
  284.                         "%s%s.font", KANJIDIR, value_head);
  285.                     break;
  286.                 default:
  287.                     break;
  288.                 }
  289.             }
  290.         }
  291.     }
  292.     else if (strlen(lp) > 0) {
  293.         if (strcmp(startup[DENEC], lp) == 0)
  294.             denec = TRUE;
  295.     }
  296.     c = fgetc(fp);
  297.     ungetc(c, fp);    /* for check EOF */
  298.  
  299.     return c;
  300. }
  301.  
  302.  
  303. #define    LINEBUFLEN    80
  304. #define    LF    '\n'    /* line feed */
  305.  
  306. char    *my_getline(FILE *fp)
  307. {
  308.     int    c, iscomment = FALSE;
  309.     static    char    linebuf[LINEBUFLEN], *lp;
  310.  
  311.     lp = linebuf;
  312.     while ((c = fgetc(fp)) != LF && c != EOF) {
  313.         if (!iscomment && isgraph(c)) {
  314.             switch (c) {
  315.             case COMMENT_MARK:
  316.                 iscomment = TRUE;
  317.                 break;
  318.             default:
  319.                 if (islower(c))
  320.                     c = toupper(c);
  321.                 *lp++ = (char)c;
  322.                 break;
  323.             }
  324.         }
  325.     }
  326.     *lp = '\0';    /* terminate */
  327.  
  328.     return linebuf;
  329. }
  330.  
  331.  
  332. VOID    init_default(VOID)
  333. {
  334.     int    i;
  335.  
  336.     denec = FALSE;
  337.     cache_size = FONT_CACHE_SIZE;
  338.     strcpy(jfontname, JFONT);    /* set default kanji font name */
  339.  
  340.     for (i = ANK; i <= KATA; i++)
  341.         *cache[i].fontname = '\0';    /* set no name */
  342. }
  343.  
  344.  
  345. int    set_cache_size(int cache_size)
  346. {
  347.     if (cache_size < FONT_CACHE_MIN)
  348.         cache_size = FONT_CACHE_MIN;
  349.     else if (cache_size > FONT_CACHE_MAX)
  350.         cache_size = FONT_CACHE_MAX;
  351.  
  352.     return cache_size;
  353. }
  354.  
  355.  
  356. /* free all resources, and exit this program. */
  357. VOID    clean_exit(char *mes, int exit_val)
  358. {
  359.     if (jFontPort)
  360.         DeletePort(jFontPort);
  361.  
  362.     CloseLib();
  363.  
  364.     if (*mes)
  365.         fprintf(stderr, "%s\n", mes);
  366.  
  367.     exit(exit_val);
  368. }
  369.